package com.apps.goods.service.impl;

import com.alibaba.fastjson.JSON;
import com.apps.goods.model.po.KupaGoodsCat;
import com.apps.goods.dao.KupaGoodsCatMapper;
import com.apps.goods.model.vo.KupaGoodsCatVo;
import com.apps.goods.service.IKupaGoodsCatService;
import com.apps.sannotation.constraints.NoNull;
import com.apps.sannotation.constraints.StrLen;
import com.apps.sannotation.service.OnRedisCache;
import com.apps.sannotation.service.enums.CacheModel;
import com.apps.saspect.ValidMethod;
import com.apps.sexctption.NullException;
import com.apps.sworld.dao.impl.sDaoImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 大鹏
 * @since 2020-10-02
 */
@OnRedisCache(model = CacheModel.ALL)
@Service
public class KupaGoodsCatServiceImpl extends sDaoImpl<KupaGoodsCatMapper, KupaGoodsCat> implements IKupaGoodsCatService
{

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Override
    public List<KupaGoodsCatVo> getMasterData() {
        return (List<KupaGoodsCatVo>) redisTemplate.opsForValue().get(this.getClass().getSimpleName()+this.currentModelClass().getSimpleName());
    }

    @ValidMethod
    @Override
    public KupaGoodsCat saveToDB(Integer father_id,
                                 @StrLen (min=2,max = 10,errMsg = "商品分类最少2个字,最多10个字") @NoNull String name)
    {
        KupaGoodsCat goodsCatFather=getOneById(father_id);
        if(father_id.intValue() > 0 && null == goodsCatFather)
            throw new NullException("商品分类"+father_id+"不存在");
        KupaGoodsCat goodsCat=new KupaGoodsCat();
        goodsCat.setFather_id(null != goodsCatFather ? goodsCatFather.getId() : 0);
        goodsCat.setName(name);
        goodsCat.setDeep(null != goodsCatFather?goodsCatFather.getDeep().intValue()+1:0);
        //以下代码过于繁琐不够美观需要优化
        if(null == goodsCatFather)
        {
            goodsCat.setFather_tree(JSON.toJSONString(new ArrayList<Integer>()));
            List<String> nameTrees = new ArrayList<>();
            nameTrees.add(name);
            goodsCat.setFather_name_tree(JSON.toJSONString(nameTrees));
        }else
        {
            List<Integer> Trees = JSON.parseArray(goodsCatFather.getFather_tree(),Integer.class);
            Trees.add(goodsCatFather.getId());
            goodsCat.setFather_tree(JSON.toJSONString(Trees));
            List<String> nameTrees = JSON.parseArray(goodsCatFather.getFather_name_tree(),String.class);
            nameTrees.add(name);
            goodsCat.setFather_name_tree(JSON.toJSONString(nameTrees));
        }
        return saveToDB(goodsCat);
    }

    /**
     * 查询出所有一级分类组织成需要的数据放入redis,压入缓存的目的是为了处理集群部署的情况
     * @return
     */
    private void QueryAndCacheMasterData()
    {
        QueryWrapper<KupaGoodsCat> wrapper=new QueryWrapper<>();
        wrapper.eq("father_id",0);
        List<KupaGoodsCat> data=query(wrapper);
        //整理数据返回结果
        List<KupaGoodsCatVo> result=new ArrayList<>();
        for(KupaGoodsCat goodsCat:data)
            result.add(new KupaGoodsCatVo(goodsCat, FindChilds(goodsCat.getId())));
        redisTemplate.opsForValue().set(this.getClass().getSimpleName()+this.currentModelClass().getSimpleName(),result);
    }

    /**
     * 找出某个分类所有的儿子
     * @param cat_id
     * @return
     */
    private List<KupaGoodsCat> FindChilds(Integer cat_id)
    {
       QueryWrapper<KupaGoodsCat> wrapper=new QueryWrapper<>();
       wrapper.eq("father_id",cat_id);
       return query(wrapper);
    }

    @Override
    public void onLoad()
    {
        //将所有一级分类加载到缓存
        QueryAndCacheMasterData();
    }

    @Override
    public void onCreate(KupaGoodsCat goodsCat)
    {
        //将所有一级分类加载到缓存
        QueryAndCacheMasterData();
    }

    @Override
    public void onUpdate(KupaGoodsCat goodsCat)
    {
        //将所有一级分类加载到缓存
        QueryAndCacheMasterData();
    }

    @Override
    public void onDelete(List<KupaGoodsCat> goodsCats)
    {
        //将所有一级分类加载到缓存
        QueryAndCacheMasterData();
    }
}
